home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TeX 1995 July
/
TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO
/
dviware
/
dvichk
/
dvichk.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-02-25
|
31KB
|
917 lines
/*
************************************************************************
* *
* Thomas Esken Software, Im Hagenfeld 84, W-4400 M"unster , GERMANY *
* ------------------------------------------------------------------ *
* *
* It is not allowed to pass on or commercialize this program, to *
* inform about the contents or part of the contents and to duplicate *
* it in any form, as far as not expressly authorized by a written *
* permit !! *
* This software doesn't claim completeness, correctitude or *
* usability. On principle I will not be liable for any damages or *
* losses, which result from using or handling my software. If you *
* use this software, you agree without any exception to this *
* agreement, which binds you legally !! *
* *
* DVIChk .C - Checks the page numbers of a TeX -> .dvi/.log-file. *
* Sketch : - 1990/11/05 - TOM , 4400 MS, BRD, Tel.:0251 / 232585 *
* Version : - 1.60-BETA - (C)opyright 1990-93 - Update:930226 *
* *
************************************************************************
Primary output from p2c, the Pascal-to-C translator !
Further modification by :
<esken@obelix.uni-muenster.de>
<find03@fx1.hrz.uni-dortmund.de>
!!! This is a BETA testing release !!!
System requirements :
---------------------
Compiler : any? ANSI-C compiler (GCC...)
Computer : Un*x Workstation (resp., Mainfraime)
RAM : about 100 KByte load size
Graphics adapter : none
Harddisk : none
Agreement of use :
------------------
Differing from the conditions of use, which are referenced in the program
header, private users or public scientific institutions are allowed to
modify this program according to their requirements resp. to adapt this
program to their target computer. For that purpose it is allowed to
translate the algorithm, which is used in this program, to an other
programing language. The modified program may be distributed only
FREE OF CHARGE as freeware or public domain software ; moreover a short
reference to me, the author of DVIChk, must be implemented in the program
documentation. In spite of the relaxation of the conditions of use, the
non guarantee clause resp. clause of exclusion of liability are valid.
Please send bug reports, extensions or improvements of this program
to me, the author !!
Short program description :
---------------------------
According to the delivered command line options, a single .dvi- resp.
.log-file, which is created by the TeX-formatter, is checked. The page
numbers, which are found in the formatted text or it's .log-file, are
shown on the standard output device in a formatted manner.
Any wildcard characters are NOT allowed in a file name !!
The format of a .dvi-file of the TeX-formatter is as follows? :
---------------------------------------------------------------
first block of data = preamble (any? sequence of bytes + date of
formatting), then 0x8b,
after this the 64bit page number xxxx,
which must be read from right to left !
further blocks of data = 0x8c0x8b, then the 64bit page number xxxx,
which must be read from right to left !
last block of data = 0x8c0xf8, then information about the used fonts.
The format of a .log-file of the TeX-formatter is as follows :
--------------------------------------------------------------
All page numbers are marked/introduced by the open bracket (== [ ). The
following character(s) must be numeral(s), e.g., [13]. The only exception
is a nested or negative page number like [13.1], so the dot and the
minus sign (roman numeral) must be respected too.
Internal set return-codes :
----------------------------
unknown command line option = 255
no file name present = 254
ask for help = 253
invalid or corrupted file = 252
Default program output is in English.
Write `#define GERMAN' below this comment
OR !! in your Makefile (-DGERMAN) for using German program output !
*/
#include "p2c.h"
#define PRGR_NAME "DVIChk"
#define VERSION_NO "v1.60-BETA"
#define pages_max 2499
#define blocksize 32767
#define suffix_dvi ".dvi"
#define suffix_log ".log"
#define id_byte_one 0x8b
#define id_byte_two 0x8c
#define id_char_one '['
#define id_char_two ']'
#define columns_max 8
#define column_width 10
#define copyright PRGR_NAME" "VERSION_NO" (c)1990-93 Thomas Esken, " \
"Im Hagenfeld 84, W-4400 M\"unster\n"
#define underline "-------------------------------------------------" \
"---------------------------\n"
#define MY_ARGC_MAX 255
#define STR_LEN_MAX 81
typedef Char string_sizeof_pathstr[STR_LEN_MAX];
typedef Char stringX[column_width+1];
typedef
enum
{
check_dvi, check_log
}
checkmode_type;
Static uchar column_quantity = 4;
Static boolean with_message = true;
Static FILE *f;
Static FILE *t;
Static uchar dvibuf[blocksize+1];
extern Char *textbuf = dvibuf;
Static stringX document_pages[pages_max+1];
Static string_sizeof_pathstr s,
fn;
Static checkmode_type mode;
Static Char textline[256];
Static unsigned short parameter_quantity,
pages,
error,
x,
i,
j;
Static boolean textline_finished,
buffer_finished,
first_buffer,
read_textline,
delete_next_bracket,
id_byte_one_found,
id_byte_two_found;
Static Char f_NAME[_FNSIZE];
Static Char t_NAME[_FNSIZE];
Static Char *pagenumber_decimal (Char *Result,
uchar a,uchar b,uchar c,uchar d)
/*
Converts the four delivered bytes, which embody a 64bit value (Hi .. Lo),
to a decimal number.
*/
{
long x;
stringX s;
x = (a >> 4) * 0x10000000L
+ (a & 15) * 0x1000000L
+ (b >> 4) * 0x100000L
+ (b & 15) * 0x10000L
+ (c >> 4) * 0x1000
+ (c & 15) * 0x100
+ d;
sprintf(s,"%ld",x);
return(strcpy(Result,s));
}
Static boolean pagenumber_ok (Char *s)
/*
Check whether the page number, which is found, is valid and no thing
like [20pt] ... etc. (log_check) !!
*/
{
boolean Result;
uchar i,j;
Result = true;
i = strlen(s);
j = 1;
while (j < i)
{
if ( ( j == 1
&& ( s[j - 1] == '-'
|| isdigit(s[j - 1])))
|| ( j > 1
&& ( s[j - 1] == '.'
|| isdigit(s[j - 1]))))
j++;
else
{
Result = false;
j = i;
}
}
return(Result);
}
Static void error_stop (unsigned short error)
/*
If an error occurs, print a corresponding message,
set the return code and terminate the program.
*/
{
if (error == 253)
{
#ifdef GERMAN
printf("+---------------------------------------------------------+\n");
printf("| "PRGR_NAME"-Hilfeseite von Thomas Esken Software (c)90-93 |\n");
printf("+---------------------------------------------------------+\n");
printf("| |\n");
printf("| "PRGR_NAME" "VERSION_NO" pr\"uft eine von TeX erstellte |\n");
printf("| .dvi/.log-Datei auf den Seitenumfang des formatierten |\n");
printf("| Textes ab und gibt die Seitenzahlen auf der Standard- |\n");
printf("| ausgabe aus. Diese Ausgabe kann in einer Textdatei |\n");
printf("| mittels der Umleitungoperators > gesichert werden ! |\n");
printf("| |\n");
printf("| Aufruf: "PRGR_NAME" [argumente...] <dateiname> |\n");
printf("| |\n");
printf("+---------------------------------------------------------+\n");
printf("| -> dateiname == .dvi/.log-Datei OHNE Wildcards (*?) |\n");
printf("+---------------------------------------------------------+\n");
printf("| -> argumente == -? (+?) == zeigt diesen Text |\n");
printf("| -[dvi][log] == Pr\"ufen der .dvi-Datei |\n");
printf("| bzw. der .log-Datei |\n");
printf("| -s[1..8] == 1..8-spaltige Ausgabe |\n");
printf("| -m[+][-] == Ausgabe mit / ohne |\n");
printf("| weiteren Informationen |\n");
printf("+---------------------------------------------------------+\n");
#else
printf("+--------------------------------------------------------+\n");
printf("| "PRGR_NAME"-help page by Thomas Esken Software (c)90-93 |\n");
printf("+--------------------------------------------------------+\n");
printf("| |\n");
printf("| "PRGR_NAME" "VERSION_NO" checks the page numbers of a |\n");
printf("| formatted text in a .dvi/.log-file which is created |\n");
printf("| by the TeX-formatter, and outputs the page numbers on |\n");
printf("| standard output. This output can be stored in a text |\n");
printf("| file via the I/O-redirection operator > !! |\n");
printf("| |\n");
printf("| Usage: "PRGR_NAME" [options...] <file name> |\n");
printf("| |\n");
printf("+--------------------------------------------------------+\n");
printf("| -> file name == .dvi/.log-file WITHOUT wildcards (*?) |\n");
printf("+--------------------------------------------------------+\n");
printf("| -> options == -? (+?) == shows this text |\n");
printf("| -[dvi][log] == checks a .dvi-file |\n");
printf("| resp., a .log-file |\n");
printf("| -s[1..8] == 1..8 column numbers |\n");
printf("| -m[+][-] == output further / |\n");
printf("| no other informations |\n");
printf("+--------------------------------------------------------+\n");
#endif
}
else
{
if (with_message)
{
fputs(copyright,stderr);
fputs(underline,stderr);
#ifdef GERMAN
fprintf(stderr,"FEHLER (%u) : ",error);
#else
fprintf(stderr,"ERROR (%u) : ",error);
#endif
switch (error)
{
case 255:
#ifdef GERMAN
fprintf(stderr,"Unbekannte Aufrufoption : %s",s);
#else
fprintf(stderr,"Unknown option : %s",s);
#endif
break;
case 254:
#ifdef GERMAN
fprintf(stderr,"Kein Dateiname angegeben");
#else
fprintf(stderr,"No file name present");
#endif
break;
case 252:
#ifdef GERMAN
fprintf(stderr,"%s ist keine ",fn);
#else
fprintf(stderr,"%s is no ",fn);
#endif
if (mode == check_dvi)
fputs(suffix_dvi,stderr);
else
fputs(suffix_log,stderr);
#ifdef GERMAN
fprintf(stderr,"-Datei oder defekt");
#else
fprintf(stderr,"-file or corrupted");
#endif
break;
default:
#ifdef GERMAN
fprintf(stderr,"Beim Verarbeiten der ");
#else
fprintf(stderr,"Processing ");
#endif
if (mode == check_dvi)
fputs(suffix_dvi,stderr);
else
fputs(suffix_log,stderr);
#ifdef GERMAN
fprintf(stderr,"-Datei %s",fn);
#else
fprintf(stderr,"-file %s",fn);
#endif
break;
}
fprintf(stderr," !!\n");
#ifdef GERMAN
fprintf(stderr,PRGR_NAME" -? (+?) f\"ur Hilfestellung\n");
#else
fprintf(stderr,PRGR_NAME" -? (+?) for help\n");
#endif
}
exit((signed int)error);
}
}
int main(int argc, Char **argv)
/*
main program DVIChk
*/
{
unsigned short FORLIM,FORLIM1;
Char STR1[256],
STR2[256],
STR3[256],
STR4[256];
Char STR5[4];
Char *TEMP;
Char *my_argv[MY_ARGC_MAX+1];
int my_argc;
Char *ptr_my_argv;
setbuf(stdout,0);
PASCAL_MAIN(argc,argv);
t = NULL;
f = NULL;
for (my_argc=0 ;
P_argv[my_argc] != NULL && my_argc < MY_ARGC_MAX;
my_argc++)
{
ptr_my_argv = malloc((unsigned)strlen(P_argv[my_argc])+1);
if (ptr_my_argv != NULL)
{
strcpy(ptr_my_argv,P_argv[my_argc]);
my_argv[my_argc] = ptr_my_argv;
}
}
my_argv[my_argc] = NULL;
my_argc = (my_argc >= MY_ARGC_MAX ? MY_ARGC_MAX : P_argc);
LABEL_start:
mode = check_dvi;
error = 0;
*fn = '\0';
if (my_argc == 1)
parameter_quantity = 1;
else
parameter_quantity = my_argc - 1;
FORLIM = parameter_quantity;
for (i=1 ; i <= FORLIM ; i++)
{
if (my_argc == 1)
strcpy(s,"?");
else
{
x = strlen(my_argv[i]);
strncpy(s,my_argv[i],STR_LEN_MAX);
if (x >= STR_LEN_MAX)
s[STR_LEN_MAX] = '\0';
}
if ( s[0] == '?'
|| ( s[0] == '-'
&& s[1] == '?')
|| ( s[0] == '+'
&& s[1] == '?'))
{
error_stop (253);
if (s[0] != '?')
exit(253);
else
{
signed char ch;
signed int i,j,k;
string_sizeof_pathstr str;
#ifdef GERMAN
printf("Eingabe [argumente] <dateiname>...");
#else
printf("Enter [options] <file name>...");
#endif
i = 0;
while ( (ch = fgetc(stdin)) != EOF
&& ch != '\n'
&& i < STR_LEN_MAX - 1)
s[i++] = ch;
s[i] = '\0';
if (!s[0])
exit(0);
else
{
i = strlen(s) - 1;
while ( isspace(s[i])
&& i >= 0)
s[i--] = '\0';
i=k = 0;
j = 1;
ptr_my_argv = my_argv[j];
while ( s[i]
&& j < MY_ARGC_MAX)
{
if (!isspace(s[i]))
str[k++] = s[i];
else
{
str[k] = '\0';
ptr_my_argv = realloc(ptr_my_argv,strlen(str)+1);
if (ptr_my_argv != NULL)
{
strcpy(ptr_my_argv,str);
my_argv[j] = ptr_my_argv;
}
k = 0;
j++;
ptr_my_argv = my_argv[j];
}
i++;
}
if (j != MY_ARGC_MAX)
{
str[k] = '\0';
ptr_my_argv = realloc(ptr_my_argv,strlen(str)+1);
if (ptr_my_argv != NULL)
{
strcpy(ptr_my_argv,str);
my_argv[j] = ptr_my_argv;
}
if (s[0])
my_argc = ++j;
}
else
if (s[0])
my_argc = j;
my_argv[j] = (Char *)NULL;
goto LABEL_start;
}
}
}
else
{
if ( s[0] == '-'
|| s[0] == '+')
{
switch (toupper(s[1]))
{
case 'D':
mode = check_dvi;
break;
case 'L':
mode = check_log;
break;
case 'M':
with_message = !(s[2] == '-');
break;
case 'S':
if ( s[2] >= '1'
&& s[2] <= (Char)(columns_max + '0'))
column_quantity = s[2] - '0';
else
column_quantity = 1;
break;
default:
error_stop (255);
}
}
else
{
strcpy(fn,s);
x = strpos2 (fn,".",1);
if ( !x
|| x == strlen(fn))
{
if (x == strlen(fn))
strdelete ((void *)fn,strlen(fn),1);
if (mode == check_dvi)
{
if (i + 1 <= parameter_quantity)
{
FORLIM1 = parameter_quantity;
for (j=i+1 ; j <= FORLIM1 ; j++)
{
strcpy(s,my_argv[j]);
if (strlen(s) >= 2)
{
if ( s[0] == '+'
|| s[0] == '-')
s[1] = toupper(s[1]);
if (strpos2 (s,"L",1))
mode = check_log;
}
}
}
}
if (mode == check_dvi)
strcat(fn,suffix_dvi);
else
strcat(fn,suffix_log);
}
else
{
if (!strcmp(strsub (STR1,fn,strlen(fn)-3,strlen(fn)),suffix_dvi))
mode = check_dvi;
else
{
if (!strcmp(strsub (STR2,fn,strlen(fn)-3,strlen(fn)),suffix_log))
mode = check_log;
else
{
if (mode == check_dvi)
sprintf(fn,"%.*s%s",x-1,strcpy(STR4,fn),suffix_dvi);
else
sprintf(fn,"%.*s%s",x-1,strcpy(STR3,fn),suffix_log);
}
}
}
}
}
}
if (*fn != '\0')
{
strcpy(t_NAME,fn);
if (t != NULL)
t = freopen(t_NAME,"r",t);
else
t = fopen(t_NAME,"r");
_SETIO(t != NULL,FileNotFound);
error = P_ioresult;
}
else
error = 254;
if (error)
error_stop (error);
if (*fn != '\0')
{
pages = 0;
textline_finished = false;
buffer_finished = false;
first_buffer = true;
read_textline = true;
delete_next_bracket = false;
id_byte_one_found = false;
id_byte_two_found = false;
if (mode == check_dvi)
{
strcpy(f_NAME,fn);
if (f != NULL)
f = freopen(f_NAME,"r+b",f);
else
f = fopen(f_NAME,"r+b");
if (f == NULL)
_EscIO(FileNotFound);
do
{
error = fread(dvibuf,1,(blocksize+1)*sizeof(uchar),f);
P_ioresult = 0;
if (error)
{
i = 0;
if (error == (unsigned short)(blocksize + 1))
error = blocksize;
buffer_finished = false;
if (first_buffer)
{
first_buffer = false;
while ( dvibuf[i] != id_byte_one
&& i < error)
i++;
if (!dvibuf[i + 5])
{
pagenumber_decimal (document_pages[pages],
dvibuf[i + 1],
dvibuf[i + 2],
dvibuf[i + 3],
dvibuf[i + 4]);
pages++;
}
i += 5;
}
while (!buffer_finished)
{
if (id_byte_one_found)
{
if (dvibuf[i] == id_byte_one)
{
if (!dvibuf[i + 5])
{
pagenumber_decimal (document_pages[pages],
dvibuf[i + 1],
dvibuf[i + 2],
dvibuf[i + 3],
dvibuf[i + 4]);
pages++;
id_byte_one_found = false;
}
i += 4;
}
else
id_byte_one_found = false;
}
if (id_byte_two_found)
{
if (!dvibuf[i + 4])
{
pagenumber_decimal (document_pages[pages],
dvibuf[i],
dvibuf[i + 1],
dvibuf[i + 2],
dvibuf[i + 3]);
pages++;
id_byte_two_found = false;
}
i += 3;
}
else
id_byte_two_found = false;
if (dvibuf[i] == id_byte_two)
{
if ( i == blocksize - 1
&& dvibuf[blocksize] == id_byte_one)
id_byte_two_found = true;
else
{
if (i == blocksize)
id_byte_one_found = true;
else
{
if ( dvibuf[i] == id_byte_two
&& dvibuf[i + 1] == id_byte_one)
{
if (!dvibuf[i + 6])
{
pagenumber_decimal (document_pages[pages],
dvibuf[i + 2],
dvibuf[i + 3],
dvibuf[i + 4],
dvibuf[i + 5]);
pages++;
}
i += 5;
}
}
}
}
if (i >= error)
buffer_finished = true;
else
i++;
}
}
} while (error);
if (f != NULL)
fclose(f);
f = NULL;
error = P_ioresult;
if (error)
error_stop (error);
strcpy(f_NAME,fn);
}
else
{
setvbuf(t,textbuf,_IOFBF,blocksize + 1);
strcpy(t_NAME,fn);
if (t != NULL)
t = freopen(t_NAME,"r",t);
else
t = fopen(t_NAME,"r");
_SETIO(t != NULL,FileNotFound);
error = P_ioresult;
if (error)
error_stop (error);
_SETIO(fgets(textline,256,t) != NULL,EndOfFile);
TEMP = strchr(textline,'\n');
if (TEMP != NULL)
*TEMP = 0;
error = P_ioresult;
if (error)
error_stop (error);
while (!P_eof(t))
{
if (read_textline)
{
_SETIO(fgets(textline,256,t) != NULL,EndOfFile);
TEMP = strchr(textline,'\n');
if (TEMP != NULL)
*TEMP = 0;
error = P_ioresult;
if (error)
error_stop (error);
}
else
read_textline = true;
i = 1;
while (i)
{
sprintf(STR5,"%c%c",id_char_one,id_char_two);
i = strpos2 (textline,STR5,1);
if (i)
strdelete ((void *)textline,i,2);
}
textline_finished = false;
sprintf(STR1,"%c",id_char_one);
i = strpos2 (textline,STR1,1);
id_byte_one_found = (i != 0);
sprintf(STR1,"%c",id_char_two);
x = strpos2 (textline,STR1,1);
id_byte_two_found = (x != 0);
if ( ( id_byte_one_found
&& ( (textline[i] > '9' || textline[i] < '0')
&& textline[i] != '-'))
|| ( i > 1
&& textline[i - 2] != ' '))
{
id_byte_one_found = false;
id_byte_two_found = false;
strdelete ((void *)textline,i,1);
}
if (id_byte_one_found)
{
if ( textline[i] != '\0'
&& !id_byte_two_found)
{
strsub (document_pages[pages],textline,i+1,strlen(textline));
if (pagenumber_ok (document_pages[pages]))
pages++;
id_byte_one_found = false;
textline_finished = true;
delete_next_bracket = true;
}
}
while ( id_byte_one_found
&& !textline_finished)
{
sprintf(STR1,"%c",id_char_two);
x = strpos2 (textline,STR1,1);
id_byte_two_found = (x != 0);
if ( id_byte_two_found
&& delete_next_bracket)
{
strcpy(textline,strsub (STR1,textline,x+1,strlen(textline)));
delete_next_bracket = false;
sprintf(STR1,"%c",id_char_two);
x = strpos2 (textline,STR1,1);
id_byte_two_found = (x != 0);
if (id_byte_one_found)
{
sprintf(STR1,"%c",id_char_one);
i = strpos2 (textline,STR1,1);
}
else
textline_finished = true;
}
if ( id_byte_two_found
&& !textline_finished)
{
if (x <= i + 1)
continue;
strsub (document_pages[pages],textline,i+1,x-i-1);
if (pagenumber_ok (document_pages[pages]))
pages++;
strcpy(textline,strsub (STR1,textline,x+1,strlen(textline)-x));
sprintf(STR1,"%c",id_char_one);
i = strpos2 (textline,STR1,1);
id_byte_one_found = (i != 0);
if ( *textline == '\0'
&& !id_byte_one_found)
textline_finished = true;
continue;
}
if (!id_byte_one_found)
break;
if ( textline[i] == '\0'
|| id_byte_two_found)
continue;
strsub (document_pages[pages],textline,i+1,strlen(textline));
if (id_byte_two_found)
{
if (pagenumber_ok (document_pages[pages]))
pages++;
id_byte_one_found = false;
textline_finished = true;
delete_next_bracket = true;
continue;
}
while ( !id_byte_two_found
&& !P_eof(t))
{
fgets(textline,256,t);
TEMP = strchr(textline,'\n');
if (TEMP != NULL)
*TEMP = 0;
sprintf(STR1,"%c",id_char_two);
x = strpos2 (textline,STR1,1);
id_byte_two_found = (x != 0);
}
if (!id_byte_two_found)
continue;
sprintf(document_pages[pages]+strlen(document_pages[pages]),
"%.*s",x-1,textline);
strcpy(textline,strsub (STR2,textline,x+1,strlen(textline)));
if (pagenumber_ok (document_pages[pages]))
pages++;
id_byte_one_found = false;
textline_finished = true;
read_textline = false;
}
if ( delete_next_bracket
&& id_byte_two_found)
delete_next_bracket = false;
}
if (t != NULL)
fclose(t);
t = NULL;
error = P_ioresult;
if (error)
error_stop (error);
}
if (with_message)
{
if (pages > 0)
{
printf("%s",copyright);
printf("%s\n",underline);
#ifdef GERMAN
printf("Dokumentdatei = %s\n",fn);
printf("Seitenanzahl insgesamt = %u\n\n",pages);
printf("Im Dokument vorhandene Seitennummern :\n");
printf("--------------------------------------\n");
#else
printf("Document file = %s\n",fn);
printf("Total page numbers = %u\n\n",pages);
printf("Page numbers existing in document :\n");
printf("-----------------------------------\n");
#endif
}
}
if (pages > 0)
{
i = 0;
x = 0;
while (i < pages)
{
if (column_quantity == 1)
fputs(document_pages[i],stdout);
else
printf("%*s",column_width,document_pages[i]);
i++;
x++;
if (x == column_quantity)
{
putchar('\n');
x = 0;
}
}
}
else
error_stop (252);
}
if (x)
putchar('\n');
if (f != NULL)
fclose(f);
if (t != NULL)
fclose(t);
return(0);
}